/*************************************************************************
	> File Name: 007.Dijkstra_HZOJ746.最短路.cpp
	> Author: Maureen 
	> Mail: Maureen@qq.com 
	> Created Time: 二  5/18 19:08:09 2021
 ************************************************************************/

#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;

//状态
struct node {
    int now, val;
    bool operator<(const node &b) const {
        return this->val > b.val;  //权值小的在上
    }
};

struct edge { //链式前向星的边的存储结构
    int e, v, next;
};

edge edges[200005]; //无向边，数量要加倍
int n, m, s, edge_cnt, head[100005], ans[100005];

void add_edge(int t1, int t2, int t3) { //加边，链式前向星存图
    edges[edge_cnt].e = t2;
    edges[edge_cnt].v = t3;
    edges[edge_cnt].next = head[t1];
    head[t1] = edge_cnt;
    edge_cnt++;
}

int main() {
    memset(head, -1, sizeof(head));
    memset(ans, 0x3F, sizeof(ans));
    scanf("%d%d%d", &n, &m, &s);
    //存边
    for (int i = 0; i < m; i++) {
        int t1, t2, t3;
        scanf("%d%d%d", &t1, &t2, &t3);
        add_edge(t1, t2, t3);
        add_edge(t2, t1, t3);
    }
    //准备
    priority_queue<node> que;
    que.push((node){s, 0});
    ans[s] = 0;
    //Dijkstra
    while (!que.empty()) {
        node temp = que.top();
        que.pop();
        if (temp.val != ans[temp.now]) {
            continue;
        }
        for (int i = head[temp.now]; i != -1; i = edges[i].next) {
            int e = edges[i].e, v = edges[i].v;
            if (ans[e] > temp.val + v) {
                ans[e] = temp.val + v;
                que.push((node){e, ans[e]});
            }
        }
    }
    //输出
    for (int i = 1; i <= n; i++) {
        if (ans[i] != 0x3f3f3f3f) {
            printf("%d\n", ans[i]);
        } else {
            printf("-1\n");
        }
    }

    return 0;
}
